//A checkers board is an 8 by 8 grid
//where half of the squares are accessible
//There are 32 total positions in the game
#ifndef __OBJC__ 
typedef char BOOL;
#define YES 1
#define NO 0
#endif

#define BOARD_W 8
#define BOARD_H 8
#define BOARD_SQRS 32

//No recorded checkers game has gone > 150 moves
#define MAX_CHECKERS_GAME 150
#define CHECKERS_MOVE_BUFFER 30

typedef int piece_t;

#define NO_PIECE 0
#define NORMAL_PIECE 1
#define KING_PIECE 2

typedef int player_t;
typedef unsigned long long hash_t;


/*Define with typedef to simply usage*/

typedef struct CheckersPos{
  char x, y;/* With-in BOARD_W and BOARD_H */
} CheckersPos;

typedef struct CheckersBoard {
  piece_t board[BOARD_SQRS];
  BOOL mustjump, iswhiteturn, isjumpseq;
  hash_t hashvalue;
  CheckersPos lastto;

/*To weaken the AI subtly, random noise can be added to evaluations*/
  int random_noise;
/*A less subtle way to weaken the AI is to randomly ignore branches of evaluation */
  int random_branch_cuts;
} CheckersBoard;

typedef struct CheckersMove{
  CheckersPos from, to;
  /*Stores whether the move is a jump and if it is a jump sequence
   *If it is a jump sequence, then the turn continues.*/
  BOOL isjump;
} CheckersMove;

/*Structure for rolling back checkers moves (for the AI)*/
typedef struct CheckersUnmove{
	CheckersMove completed_move;
	piece_t moved, captured;
	CheckersPos lastto;
	BOOL wasjumpseq;
} CheckersUnmove;


void chbInitBoard(CheckersBoard* board);

void chbInitPosition(CheckersBoard* notused, CheckersPos* pos, int sqr);

piece_t chbGetPiece(CheckersBoard* board, CheckersPos* pos);
void chbSetPiece(CheckersBoard* board, CheckersPos* pos, piece_t piece);

BOOL chbCanJumpFrom(CheckersBoard* board, CheckersPos* from);
BOOL chbCanKingJumpFrom(CheckersBoard* board, CheckersPos* from);

/*Check whether position is in board. Note that the CheckersBoard type is included
 *for uniformity in calling */
BOOL chbIsWithinBoard(CheckersBoard* notused, CheckersPos* pos);

/*Updates the checkers position stored in 'pos' to be left-forward or right-forward.
 *NB: These functions do no validation - call chbIsWithinBoard */
void chbLeftForward(CheckersBoard* board, CheckersPos* pos);
void chbRightForward(CheckersBoard* board, CheckersPos* pos);

void chbMakeMove(CheckersBoard* board, CheckersMove* move, CheckersUnmove* unmove);
void chbUnmakeMove(CheckersBoard* board, CheckersUnmove* unmove);

BOOL chbIsValidMove(CheckersBoard* board, CheckersMove* move);

/*Stores -1, 0, +1 in game result if the game is over.*/
BOOL chbIsGameOver(CheckersBoard* board, int* game_result);

/*Returns number of generated methods*/
int chbGenerateValidMoves(CheckersBoard* board, CheckersMove* moves);
void chbGenerateValidMovesFrom(CheckersBoard* board, CheckersPos* from, CheckersMove* moves, int* movecnt);
void chbGenerateValidKingMovesFrom(CheckersBoard* board, CheckersPos* from, CheckersMove* moves, int* movecnt);

void chbDisplayBoard(CheckersBoard* board);
void chbDisplayBoardWithMove(CheckersBoard* board, CheckersMove* move);
